﻿#include "ByteBuf.h"
#ifdef WIN32
#include <windows.h>
#else
#include <arpa/inet.h>
#endif
//#include <malloc.h>
#include <string.h>
#include <stdlib.h>

//void ByteBuf::check_write_resize(int len);

#define READ(type) \
	type value; \
if (readableSize() < (int)sizeof(value)) \
{ \
	return 0; \
} \
	memcpy(&value, (buf + read_pos), sizeof(value)); \
	read_pos += sizeof(value);

#define WRITE \
	check_write_resize(sizeof(value)); \
	memcpy((buf + write_pos), &value, sizeof(value)); \
	write_pos += sizeof(value);

#if CC_TARGET_PLATFORM==CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM==CC_PLATFORM_WP8 || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
//CC_TARGET_PLATFORM!=CC_PLATFORM_IOS && CC_TARGET_PLATFORM!=CC_PLATFORM_MAC

int64 ntohll(int64 val){
	return (((int64)htonl((int32)((val << 32) >> 32))) << 32) | (int64)htonl((int32)(val >> 32));
}

int64 htonll(int64 val){
	return (((int64)htonl((int32)((val << 32) >> 32))) << 32) | (int64)htonl((int32)(val >> 32));
}
#endif

void ByteBuf::check_write_resize(int len){
	check_write_resize(len, write_pos);
}

void ByteBuf::check_write_resize(int len, int pos){
	while ((pos + len) > size)
	{
		void* tmp = malloc(size * 2);
		memcpy(tmp, buf, size);
		free(buf);
		buf = (char*)tmp;
		size = size * 2;
	}
}

int ByteBuf::readableSize(){
	return write_pos - read_pos;
}

int8 ByteBuf::readInt8(){
	READ(int8);
	return value;
}

void ByteBuf::writeInt8(int8 value){
	WRITE;
}

int16 ByteBuf::readInt16(){
	READ(int16);
	value = ntohs(value);
	return value;
}

void ByteBuf::writeInt16(int16 value){
	value = htons(value);
	WRITE;
}

int32 ByteBuf::readInt32(){
	READ(int32);
	value = ntohl(value);
	return value;
}

void ByteBuf::writeInt32(int32 value){
	value = htonl(value);
	//WRITE;
	check_write_resize(sizeof(value));
	memcpy((buf + write_pos), &value, sizeof(value));
	write_pos += sizeof(value);
}

int64 ByteBuf::readInt64(){
	READ(int64);
	value = ntohll(value);
	return value;
}

void ByteBuf::writeInt64(int64 value){
	value = htonll(value);
	WRITE;
}

void* ByteBuf::readDatas(int len){
	if (readableSize() < len)
	{
		return NULL;
	}
	void* ret = buf + read_pos;
	read_pos += len;
	return ret;
}

void ByteBuf::writeDatas(const void* const datas, int len){
	check_write_resize(len);
	memcpy((buf + write_pos), datas, len);
	write_pos += len;
}

ByteBuf::ByteBuf(){
	size = 256;
	buf = (char*)malloc(size);
	read_pos = 0;
	write_pos = 0;
}

ByteBuf::~ByteBuf(){
	free(buf);
	size = 0;
	read_pos = 0;
	write_pos = 0;
}

void ByteBuf::resetRead(){
	read_pos = 0;
}

void ByteBuf::resetWrite(){
	write_pos = 0;
}

void ByteBuf::reset(){
	read_pos = 0;
	write_pos = 0;
}

void* ByteBuf::getBuf(){
	return buf;
}

void ByteBuf::writeInt32(int32 value, int pos){
	value = htonl(value);
	check_write_resize(sizeof(value), pos);
	memcpy((buf + pos), &value, sizeof(value));
}

